﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;
using System.Collections;
using TratamentoRIWikipedia.processamento;

namespace TratamentoRIWikipedia
{
    /// <summary>
    /// Ler dados do arquivo Xml e Grava em um arquivo Texto demilitando com | paipe
    /// Cada arquivo é gravado em um linha
    /// 
    /// <page>
    ///   <title>Main Page</title>
    ///   <ns>0</ns>
    ///   <id>1</id>
    /// <revision>
    ///     <id>145646</id>
    ///     <parentid>346</parentid>
    ///     <timestamp>2013-10-18T23:04:22Z</timestamp>
    ///     <contributor>
    ///         <username>Mark Holmquist</username>
    ///         <id>1</id>
    ///     </contributor>
    ///     <text xml:space="preserve" bytes="28">[[File:Test file.jpg|thumb]]</text>
    ///     <sha1>661yfvbi6ibb3ngjzn58o3ddgbhuxff</sha1>
    ///     <model>wikitext</model>
    ///     <format>text/x-wiki</format>
    /// </revision>
    /// </page>
    /// </summary>
    public class ParseXml
    {
        //Criando stream para arquivo texto
        static StreamWriter streamArq = new StreamWriter("WikiDoc01.txt");

        /// <summary>
        /// Ler conteúdo das tags title, id e text faz chamada para indentificar a codificação
        /// Limpeza de dados, Analise Léxica. 
        /// </summary>
        /// <param name="arquivoXml">Caminho do arquivo XML/ se arquivo na pasta debug só passa o nome.</param>
        public static void ParserXmlDoc(string arquivoXml)
        {
            XmlTextReader itemDoc = new XmlTextReader(arquivoXml);
            ArrayList listTag = new ArrayList { "title", "id", "text" };

            int contPage = 0;
            int idDoc = 0;
            string conteudoTag = null;

            while (itemDoc.Read())//contPage < 1000 ####para fazer com o arquivo todo, mudar aqui para itemDoc.Read() e remover do cod [itemDoc.Read()]
            {
                //itemDoc.Read();
                //Verifica se chegou ao fim do nodo page, conta o número de docs e cria novo bloco. 
                if (itemDoc.NodeType.Equals(XmlNodeType.EndElement) && itemDoc.Name.Equals("page"))
                {
                    GravaNoArquivo(streamArq, "/n", "/n");
                    idDoc = 0;//A cada nova página o id volta para zero
                    contPage++;
                }

                if (listTag.Contains(itemDoc.Name) && !(itemDoc.NodeType.Equals(XmlNodeType.EndElement)))
                {

                    if (itemDoc.Name != "id")
                    {
                        //Considera apenas tag texto e titulo para pré processamento
                        if (itemDoc.Name == "text" || itemDoc.Name == "title")
                        {
                            conteudoTag = AnaliseLexica.RemoveAcentos(itemDoc.ReadString());
                            conteudoTag = AnaliseLexica.RemoveCaracterEspecial(conteudoTag.ToLower());
                        }
                        else
                            conteudoTag = itemDoc.ReadString();
                        if(itemDoc.Name == "title")
                            GravaNoArquivo(streamArq, conteudoTag, "<#title#>");
                        if (itemDoc.Name == "text")
                            GravaNoArquivo(streamArq, conteudoTag, "<#text#>");
                        
                    }
                    else
                    {
                        //1 = Page // 2 = revision // 3 = contributor
                        idDoc++;
                        //Só grava se for id da pagina  
                        if (idDoc == 1 && !(itemDoc.NodeType.Equals(XmlNodeType.EndElement)))
                        {
                            GravaNoArquivo(streamArq, itemDoc.ReadString(),"<#id#>");
                        }
                    }
                }
            }

            FechaArquivo(streamArq, contPage);
        }



        /// <summary>
        /// Salva valor no arquivo
        /// </summary>
        /// <param name="arquivo"></param>
        /// <param name="valor"></param>
        public static void GravaNoArquivo(StreamWriter arquivo, string valor, string separador)
        {
            //Verifica se foi fim do arquivo e grava pula para linha de baixo
            if (separador != "/n")
            {
                arquivo.Write(separador);// grava o seprador 
                arquivo.Write(valor);
            }
            else
            {
                //novo bloco
                arquivo.WriteLine();
            }

        }

        public static void FechaArquivo(StreamWriter arquivo, int numDoc)
        {
            Codificao.verificarUtf8(arquivo);
            arquivo.Close();
            //Console.WriteLine("* Parse finalizado com sucesso. Qtd doc: " + numDoc +"                       *");
            //Console.WriteLine();
        }
    }
}
